﻿using Encode.Dto;

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Oracle.ManagedDataAccess.Client;
using SqlSugar;
using YSL_Domain.Model;

namespace YSL.Api.Host.Controllers
{
    /// <summary>
    /// 编码生成
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class CodeController : ControllerBase
    {
        private readonly ISqlSugarClient _db;

        public CodeController(ISqlSugarClient db)
        {
            _db = db;
        }

        /// <summary>
        /// 新建规则
        /// </summary>
        [HttpPost("rule")]
        public ActionResult<object> CreateRule([FromBody] CodeRuleCreateRequest req)
        {
            var ruleName = req.ruleName?.Trim();
            if (string.IsNullOrWhiteSpace(ruleName) || string.IsNullOrWhiteSpace(req.prefix) || req.serialLength <= 0)
                return BadRequest(new { success = false, message = "参数不完整" });

            var exists = _db.Queryable<CODE_RULE>().Any(x => x.RULE_NAME.Trim().ToUpper() == ruleName.ToUpper());
            if (exists)
                return BadRequest(new { success = false, message = "规则名已存在" });

            var rule = new CODE_RULE
            {
                RULE_NAME = req.ruleName,
                PREFIX = req.prefix,
                CONNECTOR = string.IsNullOrEmpty(req.connector) ? "_" : req.connector,
                SERIAL_LENGTH = req.serialLength
            };

            try
            {
                _db.Insertable(rule).ExecuteCommand();
            }
            //catch (OracleException ex) when (ex.Number == 1) // ORA-00001 唯一约束
            //{
            //    return BadRequest(new { success = false, message = "规则名已存在（唯一约束）" });
            //}
            catch (Exception ex)
            {
                // 其它异常
                return StatusCode(500, new { success = false, message = "服务器异常：" + ex.Message });
            }

            return Ok(new { success = true, message = "规则创建成功" });
        }
        /// <summary>
        /// 编码预览
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>

        [HttpPost("preview")]
        public ActionResult<object> PreviewCode([FromBody] CodeGenerateRequest req)
        {
            if (string.IsNullOrWhiteSpace(req.ruleName))
                return BadRequest(new { success = false, message = "规则名不能为空" });

            string dateStr = DateTime.Now.ToString("yyyyMMdd");
            var rule = _db.Queryable<CODE_RULE>().First(x => x.RULE_NAME == req.ruleName.Trim());
            if (rule == null)
                return BadRequest(new { success = false, message = "规则不存在" });

            var serial = _db.Queryable<CODE_SERIAL>()
                .Where(x => x.RULE_NAME == req.ruleName && x.DATE_STR == dateStr)
                .First();

            int nextSerial = serial == null ? 1 : Convert.ToInt32(serial.CURRENT_SERIAL) + 1;
            string serialStr = nextSerial.ToString().PadLeft(Convert.ToInt32(rule.SERIAL_LENGTH), '0');
            string connector = !string.IsNullOrEmpty(req.connector)
                ? req.connector
                : (!string.IsNullOrEmpty(rule.CONNECTOR) ? rule.CONNECTOR : "_");

            string code = string.IsNullOrEmpty(connector)
                ? $"{rule.PREFIX}{dateStr}{serialStr}"
                : $"{rule.PREFIX}{connector}{dateStr}{connector}{serialStr}";

            return Ok(new { code });
        }

        /// <summary>
        /// 保存编码
        /// </summary>
        [HttpPost("generate")]
        public ActionResult<object> GenerateCode([FromBody] CodeGenerateRequest req)
        {
            if (string.IsNullOrWhiteSpace(req.ruleName))
                return BadRequest(new { success = false, message = "规则名不能为空" });

            string dateStr = DateTime.Now.ToString("yyyyMMdd");
            var rule = _db.Queryable<CODE_RULE>().First(x => x.RULE_NAME == req.ruleName.Trim());
            if (rule == null)
                return BadRequest(new { success = false, message = "规则不存在" });

            int nextSerial = 1;

            _db.Ado.BeginTran();
            try
            {
                var serial = _db.Queryable<CODE_SERIAL>()
                    .Where(x => x.RULE_NAME == req.ruleName && x.DATE_STR == dateStr)
                    .First();

                if (serial == null)
                {
                    _db.Insertable(new CODE_SERIAL
                    {
                        RULE_NAME = req.ruleName,
                        DATE_STR = dateStr,
                        CURRENT_SERIAL = 1
                    }).ExecuteCommand();
                    nextSerial = 1;
                }
                else
                {
                    nextSerial = Convert.ToInt32(serial.CURRENT_SERIAL) + 1;
                    serial.CURRENT_SERIAL = nextSerial;
                    _db.Updateable(serial)
                        .Where(x => x.RULE_NAME == req.ruleName && x.DATE_STR == dateStr)
                        .ExecuteCommand();
                }
                _db.Ado.CommitTran();
            }
            catch (Exception ex)
            {
                _db.Ado.RollbackTran();
                // 建议记录日志
                return StatusCode(500, new { success = false, message = "生成编码失败" });
            }

            string serialStr = nextSerial.ToString().PadLeft(Convert.ToInt32(rule.SERIAL_LENGTH), '0');

            // 优先用请求的CONNECTOR，其次用规则表的CONNECTOR，最后默认下划线
            string connector = !string.IsNullOrEmpty(req.connector)
                ? req.connector
                : (!string.IsNullOrEmpty(rule.CONNECTOR) ? rule.CONNECTOR : "_");

            string code = string.IsNullOrEmpty(connector)
                ? $"{rule.PREFIX}{dateStr}{serialStr}"
                : $"{rule.PREFIX}{connector}{dateStr}{connector}{serialStr}";

            return Ok(new { code });
        }

        /// <summary>
        /// 获取规则详情
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost("rule/detail")]
        public ActionResult<object> GetRuleDetail([FromBody] CodeRuleDetailRequest req)
        {
            if (string.IsNullOrWhiteSpace(req.ruleName))
                return BadRequest(new { success = false, message = "规则名不能为空" });

            var rule = _db.Queryable<CODE_RULE>().First(x => x.RULE_NAME == req.ruleName);
            if (rule == null)
                return NotFound(new { success = false, message = "规则不存在" });

            return Ok(new
            {
                ruleName = rule.RULE_NAME,
                prefix = rule.PREFIX,
                connector = rule.CONNECTOR,
                serialLength = rule.SERIAL_LENGTH
            });
        }
        /// <summary>
        /// 获取所有规则名
        /// </summary>
        [HttpGet("rules")]
        public ActionResult<object> GetRules()
        {
            var rules = _db.Queryable<CODE_RULE>()
        .Select(x => new
        {
            ruleName = x.RULE_NAME,
            prefix = x.PREFIX,
            connector = x.CONNECTOR,
            serialLength = x.SERIAL_LENGTH
        }).ToList();
            return Ok(new { rules });

        }
    }
}
